package cn.codeforfun.utils;

import cn.codeforfun.generator.mapper.*;
import cn.codeforfun.generator.model.*;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.web.servlet.MockMvc;

import javax.annotation.Resource;
import java.util.UUID;

/**
 * @author wangbin
 */
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
@ActiveProfiles("unit-test")
public abstract class BaseTest {
    @Resource
    protected MockMvc mockMvc;
    @Resource
    protected ResourceMapper resourceMapper;
    @Resource
    protected RoleMapper roleMapper;
    @Resource
    protected UserMapper userMapper;
    @Resource
    protected ClientMapper clientMapper;
    @Resource
    protected UserRoleMapper userRoleMapper;
    @Resource
    protected RoleResourceMapper roleResourceMapper;
    protected PasswordEncoder encoder = new BCryptPasswordEncoder();

    protected String username = "admin";
    protected String password = "admin";
    protected String clientId = "client";
    protected String clientSecret = "secret";
    protected String redirectUri = "http://localhost:4200/login";

    @BeforeEach
    void setUp() {
        cn.codeforfun.generator.model.Resource resource1 = cn.codeforfun.generator.model.Resource.builder()
                .id(UUID.randomUUID().toString()).name("user").description("普通用户资源").build();
        cn.codeforfun.generator.model.Resource resource2 = cn.codeforfun.generator.model.Resource.builder()
                .id(UUID.randomUUID().toString()).name("admin").description("管理员资源").build();
        resourceMapper.insertSelective(resource1);
        resourceMapper.insertSelective(resource2);

        Role role1 = Role.builder().id(UUID.randomUUID().toString()).name("user").description("普通用户").build();
        Role role2 = Role.builder().id(UUID.randomUUID().toString()).name("admin").description("系统管理员").build();
        roleMapper.insertSelective(role1);
        roleMapper.insertSelective(role2);

        RoleResource roleResource1 = RoleResource.builder().roleId(role1.getId()).resourceId(resource1.getId()).build();
        RoleResource roleResource2 = RoleResource.builder().roleId(role2.getId()).resourceId(resource1.getId()).build();
        RoleResource roleResource3 = RoleResource.builder().roleId(role2.getId()).resourceId(resource2.getId()).build();
        roleResourceMapper.insertSelective(roleResource1);
        roleResourceMapper.insertSelective(roleResource2);
        roleResourceMapper.insertSelective(roleResource3);

        User user1 = User.builder().id(UUID.randomUUID().toString()).username("user").password(encoder.encode("user")).build();
        User user2 = User.builder().id(UUID.randomUUID().toString()).username("admin").password(encoder.encode("admin")).build();
        userMapper.insertSelective(user1);
        userMapper.insertSelective(user2);

        UserRole userRole1 = UserRole.builder().userId(user1.getId()).roleId(role1.getId()).build();
        UserRole userRole2 = UserRole.builder().userId(user2.getId()).roleId(role1.getId()).build();
        UserRole userRole3 = UserRole.builder().userId(user2.getId()).roleId(role2.getId()).build();
        userRoleMapper.insertSelective(userRole1);
        userRoleMapper.insertSelective(userRole2);
        userRoleMapper.insertSelective(userRole3);

        Client client1 = Client.builder()
                .id(UUID.randomUUID().toString())
                .clientId(clientId)
                .clientSecret(encoder.encode(clientSecret))
                .clientAuthorizedGrantTypes("authorization_code,password,client_credentials,refresh_token,implicit")
                .clientRegisteredRedirectUri(redirectUri)
                .clientScope("app")
                .clientAutoApproveScope("app")
                .clientAccessTokenValiditySeconds(7200)
                .clientRefreshTokenValiditySeconds(604800)
                .build();
        clientMapper.insertSelective(client1);
    }

    @AfterEach
    void tearDown() {
        userRoleMapper.delete(new UserRole());
        roleResourceMapper.delete(new RoleResource());
        userMapper.delete(new User());
        clientMapper.delete(new Client());
        roleMapper.delete(new Role());
        resourceMapper.delete(new cn.codeforfun.generator.model.Resource());
    }
}
